#lang racket
(require racket/tcp)

;; Mode is one of :
;;  - hibernate
;;  - sleep
;;  - lock
(define mode (make-parameter null))

(define args
  (command-line
   #:multi
   [("-m" "--mode") m
                    "Specify the mode"
                    (mode m)]))

;; Gets the message from the server/input port
(define (read-msg)
  (read-line input))

;; whatdo? : String -> String
;; Handles what to do when a message is received
(define (whatdo? msg)
  (when (eof-object? msg) (exit))
  (cond 
    [(string=? msg "hibernate") (hiber)]
    [(string=? msg "validate") (valid)])
  (display msg))

;; Closes the ports when disconnected
(define (close-ports)
  (with-handlers ([exn:fail:network? (λ (e) (void))])
    (tcp-abandon-port input)
    (tcp-abandon-port output)))

;; Connects to the server
(define (open-ports)
  (tcp-connect "192.168.0.103" 1121))

;; Gets the input/output ports
(define (create-ports)
  (let-values ([(in out) (open-ports)])
    (set! input in)
    (set! output out)))

;; Hibernates the client
(define (hiber)
  (close-ports)
  (system
   (case (system-type)
     [(windows) "\"C:\\Program Files (x86)\\Racket\\Racket.exe\" popup-shutdown.rkt"]
     [(unix macosx) "racket popup-shutdown.rkt"])))

(define (valid)
  (with-handlers ([exn:fail:network? (λ (e) (close-ports)
                                       (create-ports))])
    (displayln "valid" output)
    (flush-output output)))
  
  
;; run
(define-values (input output) (open-ports))

(let loop ()
  (whatdo? (read-msg))
  (loop))